module Aio::Base::Toolkit
  module WordWps
    class Word

      include Aio::Ui::Verbose

      def initialize(encoding = "utf-8")

        if Aio::Base::Toolkit::OS.windows?
          require "win32ole"
        else
          print_error "只有Windows系统才能使用Excel模块"
          exit 0
        end 


        @word = WIN32OLE.new("Word.Application")
        @word.visible = false
        @encoding = encoding
      end

      # 警告提示开关
      def display_alerts=(bool)
        @word.DisplayAlerts = bool
      end

      def init_document
        @document = @word.Documents.add
        return Document.new(@document, @word)
      end


      def show
        @word.visible = true
      end

      def save(path)
        @document.saveas(path)
      end

      def close
        @document.close
        @word.quit
      end
    end

    # 对文本控件的调用
    class Document

      def initialize(document, word)
        @doc_work = document
        @word = word
        #@text = Text.new(@word.Selection, self)
        create_style
      end

      # ActiveDocument
      def doc_work
        @doc_work
      end

      # 自动化对象
      def word_basic
        doc_work.Application.WordBasic
      end

      # 创建样式
      def create_style

        # 正文 楷体五号
        sty = @doc_work.styles("正文")
        sty.font.size = 10
        sty.font.NameFarEast = "宋体"
        sty.font.NameAscii = "Times New Roman"
        sty.font.NameOther = "Times New Roman"
        sty.ParagraphFormat.Alignment = 3
        sty.ParagraphFormat.LineSpacingRule = 1
        sty.NextParagraphStyle = "正文"

        # 楷体3号字体
        sty = @doc_work.styles.add("Cover 1", 1)
        sty.font.size = 16
        sty.font.NameFarEast = "楷体"
        sty.font.NameAscii = "Times New Roman"
        sty.font.NameOther = "Times New Roman"
      end

      # 由实例自己创建风格
      def create_style_self(name)
        sty = @doc_work.styles.add(name, 1)
        yield sty
      end

      # 返回Selection
      def now
        @word.Selection
      end

      # 返回Text类
      def add_text
        return Text.new(@word.Selection, self)
        entry
      end

      # 风格设置
      def styles(name)
        @doc_work.Styles(name)
      end

      # 设置表格
      def add_table(row, col)
        @doc_work.tables.add(now.Range, row, col)
      end

      # 创建目录
      def create_catalog
        #range = doc_work.Range(0, 0)
        range = now.range
        doc_work.TablesOfContents.Add(
          range,		# Range
          true,			# UseHeadingStyles
          1,				# UpperHeadingLevel
          3,				# LowerHeadingLevel default: 9
          false,		# UseFields
          nil,			# TableId
          true,			# RightAlignPageNumbers
          true,			# IncludePageNumbers
          "",				# AddedStyles
          true,			# UseHyperlinks
          true,			# HidePageNumbersInWeb
          true,			# UseOutlineLevels default: false
        )

        # 换到下一行
        move_down
      end

      # 更新目录
      def update_catalog
        word_basic.UpdateTableOfContents
      end

      # 回车
      def entry
        now.TypeParagraph
      end

      # 移动到行首
      def home_key
        now.HomeKey(5)
      end

      # 移动到行尾
      def end_key
        now.EndKey(5)
      end

      # 移动到下一行
      def move_down
        self.end_key
        self.entry
      end

      # 右移
      # count 数值, 移动距离
      # ext  0or1 , 是否扩展
      # unit  wdCharachter
      def move_right(count=nil, ext=nil, unit=nil)
        now.MoveRight(unit, count, ext)
      end

      # 将厘米换算成磅
      def cent_to_point(int)
        @word.CentimetersToPoints(int)
      end

    end

    # 只对内容服务
    class Text

      def initialize(selection, document)
        # 现在所选项
        @selection = selection

        # Document 类
        @document = document
      end

      # ActiveDocument
      def doc_work
        @document.doc_work
      end

      # ActiveDocument.Selecton
      def now
        @selection
      end

      # 调整字体
      def font
        now.Font
      end

      # 调整字体大小
      def size=(int)
        self.font.Size = int
      end

      # 文本左对齐
      def left
        now.ParagraphFormat.Alignment = 0
      end

      # 文本居中
      def center
        now.ParagraphFormat.Alignment = 1
      end

      # 文本右对齐
      def right
        now.ParagraphFormat.Alignment = 2
      end

      # 两端对其
      def justify
        now.ParagraphFormat.Alignment = 3
      end

      # 回车
      def entry
        @document.entry
      end

      # 移动到下一行
      def move_down
        @document.move_down
      end

      # 写入元数据
      def print(str)
        now.TypeText(str)
      end

      # 写入数据,抬头Tab, 并且换行
      def puts(str)
        now.TypeText("\t" + str)
        self.entry
      end

      # 替换,并替换风格
      def replace(find, replace, style)
        rep_opt = now.Find
        rep_opt.ClearFormatting
        rep_opt.Replacement.ClearFormatting
        rep_opt.Replacement.Style = doc_work.Styles(style)
        rep_opt.Text = find
        rep_opt.Replacement.Text = replace
        rep_opt.Forward = true
        rep_opt.wrap = 1		# 到达开头或结尾时继续搜索
        rep_opt.Format = true
        rep_opt.MatchCase = false
        rep_opt.MatchWholeWord = false
        rep_opt.MatchByte = true
        rep_opt.MatchWildcards = false
        rep_opt.MatchSoundsLike = false
        rep_opt.MatchAllWordForms = false

        rep_opt.Execute(nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,1)
      end


      # 设置风格
      def style(name)
        now.Style = @document.styles(name)
      end

      # 按一个段设置风格和内容
      def section(style_name=nil)
        self.style(style_name) unless style_name.nil?
        res = yield
        if res.kind_of? ::Array
          res.join("\n")
        end
        print(res)
        self.entry
      end

      # 插入表格,并返回Table类
      def insert_table(row, col)
        obj = @document.add_table(row, col)
        Table.new(now, row, col, obj)
      end

      # 插入表格
      def add_table(row, col, &block)
        table = insert_table(row, col)
        block.call(table)

        # 跳出表格
        now.MoveDown(5, 1)
      end

      # 通过已有的数组插入表格
      def add_table_by_value(tbl, &block)
        row = tbl.size
        col = tbl[0].size
        table = insert_table(row, col)
        block.call(table)

        # 保证在写入数据的时候在第一个单元格
        table.top
        # 一维化数组
        table << tbl.flatten
        # 跳出表格
        now.MoveDown(5, 1)
      end

      # 插入头部的图片
      def add_head_image(path)
        self.first_line_indent = -2
        add_image(path)
        picture_size(1.25)
        self.entry
        self.first_line_indent = 0
      end

      # 插入图片
      def add_image(path)
        now.InlineShapes.AddPicture(path, false, true)
      end

      # 修改首行缩进(厘米)
      def first_line_indent=(cent)
        now.ParagraphFormat.FirstLineIndent = @document.cent_to_point(cent)
      end

      # 修改最近一个图片尺寸倍数
      def picture_size(int)
        num = doc_work.InlineShapes.Count
        pic = doc_work.InlineShapes(num)
        pic.width *= int
      end

      # 插入一条横线
      def insert_line

        # 通过导入图片的方法
        path = File.join(BaseFile, "aio", "resource", "line.png")
        self.add_image(path)
        self.move_down
      end

      # 绘制图表
      # 测试图表
      #tbl = [ 
      #  ["a", "1"],
      #  ["b", "2"],
      #  ["c", "3"],
      #  ["d", "4"],
      #]
      #text.chart(tbl) do |chart|
      #  chart.title = "Name"
      #  chart.type = 5 
      #  #chart.axes_x = "year"
      #  #chart.axes_y = "value"
      #  chart.style = 251 
      #end
      def chart(tbl, &block)

        # 当没有内容的时候，则不绘制
        return nil if tbl.empty?

        begin
          excel = ExcelWps::WorkBook.new
          #excel.show
          excel.display_alerts = false
          worksheet = excel.add_worksheet("sheet")
          tbl.each do |r|
            worksheet.add_row { |row| row << r }
          end

          # 获取结束的单元格
          col = tbl[0].size
          end_cell = worksheet.current_row.cell_name(col - 1)

          worksheet.add_chart do |chart|
            chart.source = worksheet.range("A1:#{end_cell}")
            block.call(chart)
          end
        ensure
          excel.close
        end

        self.style("正文")
        self.center
        doc_work.Application.Selection.PasteAndFormat(13)

        # 移动到下一行
        self.move_down
        self.left
      end

      # 插入分页符
      def page_break
        now.InsertBreak(7)
      end

      alias :style= :style
    end

    # 表格
    class Table
      def initialize(selection, row, col, obj)
        @row = row
        @col = col
        @count = row * col
        @selection = selection
        @obj = obj
      end

      def now
        @selection
      end

      # 合并列
      def merge_row
        now.SelectRow
        now.Cells.Merge
        @count = @count - @row + 1
      end

      # 放入数据
      def puts(str)
        now.SelectCell
        now.TypeText(str)
        @count -= 1
        now.MoveRight(12) unless @count < 1
      end

      # 放入数据, 可以按数组放入
      def <<(arr)
        case arr
        when ::String
          puts(arr)
        when ::Array
          arr.each { |a| puts(a) }
        end
      end

      # 设置行高
      def height=(point)
        now.Rows.Height = point
      end

      # 设置风格
      def style=(sty)
        select_all
        now.Style = sty
      end

      # 设置列宽度
      def set_columns_width(col, point)
        @obj.Columns(col).SetWidth(point, 2)
      end

      # 移动到第一个单元格
      def top
        @obj.Cell(1,1).Select
      end

      # 居中
      def center
        select_all
        now.ParagraphFormat.Alignment = 1
      end

      # 选择整个表格
      def select_all
        @obj.Select
      end

      # 网格线
      def border_line
        select_all
        now.Borders(-1).LineStyle = 1
        now.Borders(-2).LineStyle = 1
        now.Borders(-3).LineStyle = 1
        now.Borders(-4).LineStyle = 1
        now.Borders(-5).LineStyle = 1
        now.Borders(-6).LineStyle = 1
      end
    end

  end
end
